/*
 * Copyright 2002-2024 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.support;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanCreationNotAllowedException;
import org.springframework.beans.factory.BeanCurrentlyInCreationException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.SingletonBeanRegistry;
import org.springframework.core.SimpleAliasRegistry;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

/**
 * Generic registry for shared bean instances, implementing the
 * {@link org.springframework.beans.factory.config.SingletonBeanRegistry}.
 * Allows for registering singleton instances that should be shared
 * for all callers of the registry, to be obtained via bean name.
 *
 * <p>Also supports registration of
 * {@link org.springframework.beans.factory.DisposableBean} instances,
 * (which might or might not correspond to registered singletons),
 * to be destroyed on shutdown of the registry. Dependencies between
 * beans can be registered to enforce an appropriate shutdown order.
 *
 * <p>This class mainly serves as base class for
 * {@link org.springframework.beans.factory.BeanFactory} implementations,
 * factoring out the common management of singleton bean instances. Note that
 * the {@link org.springframework.beans.factory.config.ConfigurableBeanFactory}
 * interface extends the {@link SingletonBeanRegistry} interface.
 *
 * <p>Note that this class assumes neither a bean definition concept
 * nor a specific creation process for bean instances, in contrast to
 * {@link AbstractBeanFactory} and {@link DefaultListableBeanFactory}
 * (which inherit from it). Can alternatively also be used as a nested
 * helper to delegate to.
 *
 * @author Juergen Hoeller
 * @since 2.0
 * @see #registerSingleton
 * @see #registerDisposableBean
 * @see org.springframework.beans.factory.DisposableBean
 * @see org.springframework.beans.factory.config.ConfigurableBeanFactory
 */
/** 
 *  对接口SingletonBeanRegistry各函数的实现
 *
 *  共享bean实例的通用注册表，实现了SingletonBeanRegistry。允许注册单例实例，
 *  该实例应该为注册中心的所有调用者共享，并通过bean名称获得。还支持一次性bean实例
 *  的注册(它可能对应于已注册的单例，也可能不对应于已注册的单例)，在注册表关闭时销毁。
 *  可以注册bean之间的依赖关系，以强制执行适当的关闭顺序
 */
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {

	/** Maximum number of suppressed exceptions to preserve. */
	private static final int SUPPRESSED_EXCEPTIONS_LIMIT = 100;

	//  一级缓存：用于保存BeanName和创建bean实例之间的关系
	// ====== 一级缓存：单例（对象）池。这里面的对象都是确保初始化完成，可以被正常使用的。它可能来自3级，或者2级
	// ###### 单例池
	/** Cache of singleton objects: bean name to bean instance. */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

	//  三级缓存：用于保存BeanName和创建bean的工厂之间的关系
	/**
	 * ====== 三级缓存：单例工厂池。这里面不是bean本身，是它的一个工厂，未来调getObject来获取真正的bean
	 * 一旦获取，就从这里删掉，进入2级（发生闭环的话）或1级（没有闭环）
	 */
	/** Cache of singleton factories: bean name to ObjectFactory. */
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

	/* 
	 * 二级缓存：保存BeanName和创建bean实例之间的关系，与singletonFactories的不同之处在于，当一个单例bean被放到这里之后，那么当bean还在创建过程中
	 * 就可以通过getBean方法获取到，可以方便进行循环依赖的检测
	 */
	/**
	 * ====== 二级缓存：早期（对象）单例池
	 * 这里面都是半成品，只是有人用它提前从3级get出来，把引用暴露出去
	 * 它里面的属性可能是null，所以叫早期对象，early！半成品
	 * 未来在getBean赋完属性后，会调addSingleton清掉2级，正式进入1级
	 */
	/** Cache of early singleton objects: bean name to bean instance. */
	private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);

	//  用来保存当前所有已经注册的bean
	// ====== 一组已注册的单例实例，按注册顺序包含bean名称
	/** Set of registered singletons, containing the bean names in registration order. */
	private final Set<String> registeredSingletons = new LinkedHashSet<>(256);

	//  正在创建过程中的beanName集合
	// ====== 当前正在创建的bean的名称
	/** Names of beans that are currently in creation. */
	private final Set<String> singletonsCurrentlyInCreation =
			Collections.newSetFromMap(new ConcurrentHashMap<>(16));

	//  当前在创建检查中排除的bean名
	// ====== 当前排除在创建bean名称中的检查
	/** Names of beans currently excluded from in creation checks. */
	private final Set<String> inCreationCheckExclusions =
			Collections.newSetFromMap(new ConcurrentHashMap<>(16));

	//  抑制的异常列表，可用于关联相关原因
	/** Collection of suppressed Exceptions, available for associating related causes. */
	@Nullable
	private Set<Exception> suppressedExceptions;

	//  指示我们当前是否在destroySingletons中的标志
	// ====== 指示当前是否在DestroySingleton中的标志
	/** Flag that indicates whether we're currently within destroySingletons. */
	private boolean singletonsCurrentlyInDestruction = false;

	//  一次性Bean实例：bean名称 - DisposableBean实例
	/** Disposable bean instances: bean name to disposable instance. */
	private final Map<String, DisposableBean> disposableBeans = new LinkedHashMap<>();

	//  在包含的Bean名称之间映射：bean名称 - Bean包含的Bean名称集
	/** Map between containing bean names: bean name to Set of bean names that the bean contains. */
	private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);

	// ###### 某个Bean被哪些Bean依赖了
	/** Map between dependent bean names: bean name to Set of dependent bean names. */
	private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);

	// ###### 某个Bean依赖了哪些Bean
	/** Map between depending bean names: bean name to Set of bean names for the bean's dependencies. */
	private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);

	// 将beanName和singletonObject的映射关系添加到该工厂的单例缓存中
	@Override
	public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
		Assert.notNull(beanName, "Bean name must not be null");
		Assert.notNull(singletonObject, "Singleton object must not be null");
		// 使用singletonObjects作为锁，保证线程安全
		synchronized (this.singletonObjects) {
			// 获取beanName在singletonObjects中的单例对象
			//====== 缓存查找
			Object oldObject = this.singletonObjects.get(beanName);
			// 如果成功获得对象
			if (oldObject != null) { //====== 如果缓存有重复的，抛异常
				// 非法状态异常：不能注册对象[singletonObject]，在bean名'beanName'下，已经有对象[oldObject]
				throw new IllegalStateException("Could not register object [" + singletonObject +
						"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
			}
			// 将beanName和singletonObject的映射关系添加到该工厂的单例缓存中
			//====== 放进缓存，其实就是个Map
			addSingleton(beanName, singletonObject);
		}
	}

	/**
	 * Add the given singleton object to the singleton cache of this factory.
	 * <p>To be called for eager registration of singletons.
	 * @param beanName the name of the bean
	 * @param singletonObject the singleton object
	 */
	// 将beanName和singletonObject的映射关系添加到该工厂的单例缓存中
	//====== bean实例化完后 ，放到一级缓存！清除2、3级！
	protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			// 将映射关系添加到单例对象的高速缓存中
			//====== 实例后、装配后 设置一级缓存
			this.singletonObjects.put(beanName, singletonObject);
			// 移除beanName在单例工厂缓存中的数据
			//====== 实例后、装配后 移除三级缓存
			this.singletonFactories.remove(beanName);
			// 移除beanName在早期单例对象的高速缓存的数据
			//====== 移除二级缓存
			this.earlySingletonObjects.remove(beanName);
			// 将beanName添加到已注册的单例集中
			//====== 一个set，记录了单例的所有bean的名字
			this.registeredSingletons.add(beanName);
		}
	}

	/**
	 * Add the given singleton factory for building the specified singleton
	 * if necessary.
	 * <p>To be called for eager registration of singletons, e.g. to be able to
	 * resolve circular references. - 为解决循环依赖，创建早期对象时会调它
	 * @param beanName the name of the bean
	 * @param singletonFactory the factory for the singleton object
	 */
	// 如果需要，添加给定的单例对象工厂来构建指定的单例对象
	//====== 添加factory到三级缓存
	protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(singletonFactory, "Singleton factory must not be null");
		// 使用singletonObjects进行加锁，保证线程安全
		synchronized (this.singletonObjects) {
			// 如果单例对象的高速缓存【beam名称-bean实例】没有beanName的对象
			if (!this.singletonObjects.containsKey(beanName)) {
				//  将beanName,singletonFactory放到单例工厂的缓存【bean名称 - ObjectFactory】
				// ====== 实例化后、注入之前；获取早期引用对象getEarlyBeanReference,
				// ====== 放到三级缓存，注意，放进去的只是个ObjectFactory，它封装了bean的创建方法
				// ====== 但是还没创建，在getObject调用的时候才会产出实际的bean
				this.singletonFactories.put(beanName, singletonFactory);
				//  从早期单例对象的高速缓存【bean名称-bean实例】 移除beanName的相关缓存对象
				this.earlySingletonObjects.remove(beanName);
				//  将beanName添加已注册的单例集中
				this.registeredSingletons.add(beanName);
			}
		}
	}

	/** 
	 *  获取beanName的单例对象，并允许创建早期引用
	 *  @param beanName the name of the bean to look for
	 *  @return
	 */
	@Override
	@Nullable
	public Object getSingleton(String beanName) {
		//  获取beanName的单例对象，并允许创建早期引用
		//参数true设置标识允许早期依赖
		return getSingleton(beanName, true); // ===>
	}

	/**
	 * Return the (raw) singleton object registered under the given name.
	 * <p>Checks already instantiated singletons and also allows for an early
	 * reference to a currently created singleton (resolving a circular reference).
	 * @param beanName the name of the bean to look for
	 * @param allowEarlyReference whether early references should be created or not
	 * @return the registered singleton object, or {@code null} if none found
	 */
	// ====== 单例池:
	/**
	   ====== 循环依赖问题解决点！【关键点】 在A-B-A的doGetBean里多次调用这个方法每次行为不一样
	   ====== allowEarlyReference：要不要生成2级缓存，
	   ====== 如果true，就从3级的getObject生成，放入2级缓存，并清除3级，循环依赖的时候会触发
	 */
	@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		// Quick check for existing instance without full singleton lock
		//  从单例对象缓存中获取beanName对应的单例对象
		// ====== 先从一级缓存中拿
		// 检查缓存中是否存在实例
		Object singletonObject = this.singletonObjects.get(beanName);
		//  如果单例对象缓存中没有，并且该beanName对应的单例bean正在创建中
		/** ======
		   后面if的行为很重要，有多种触发时机，以循环依赖A-B-A为例
		   1、重点看isSingletonCurrentlyInCreation的值，这里面A第一次路过肯定是空的
		   2、A到getSingleton(Factory{createBean})方法里的时候，这个值会放入A
		   3、A发现需要B，B走到这里，依然是空的
		   4、B发现需要A，A的getBean再次走到这里，第2步里放进了A,不再空，会进入这个if
		   5、A进入if，发现2级缓存为null，会触发3级缓存升2级，升完返回给B，B就完整了
		 */
		// 第一次创建isSingletonCurrentlyInCreation(beanName)为false,若当前 bean正在创建则为true
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			//  从早期单例对象缓存中获取单例对象（之所称成为早期单例对象，是因为earlySingletonObjects里
			//  的对象的都是通过提前曝光的ObjectFactory创建出来的，还未进行属性填充等操作）
			// ====== 再从二级缓存拿
			//如果此bean正在加载则不处理
			singletonObject = this.earlySingletonObjects.get(beanName);
			//  如果在早期单例对象缓存中也没有，并且允许创建早期单例对象引用
			// ====== allowEarlyReference是否允许循环依赖
			if (singletonObject == null && allowEarlyReference) {
				//  如果为空，则锁定全局变量并进行处理
				synchronized (this.singletonObjects) {
				/******************************************************************************************/
					// Consistent creation of early reference within full singleton lock
					singletonObject = this.singletonObjects.get(beanName);
						if (singletonObject == null) {
							singletonObject = this.earlySingletonObjects.get(beanName);
						if (singletonObject == null) {
				/******************************************************************************************/
							// ====== 注意！循环依赖A-B-A ， 在B里面设置A，触发getBean(A)的时候会进这里
							// ====== 在从三级缓存拿，发现三级缓存有了，此处来结束这个死循环A--B--A
							//+ 当某些方法需要提前初始化的时候则会调用 addSingletonFactory方法将对应的ObjectFactory初始化策略存储在singletonFactories
							ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
							if (singletonFactory != null) {
								//  如果存在单例对象工厂，则通过工厂创建一个单例对象
								// ====== 调用早期对象方法AbstractAutowireCapableBeanFactory.getEarlyBeanReference
								// ====== 这货是在doCreateBean时放入三级缓存的一个lambda表达式，记得不?
								//调用预先设定的getObject方法
								singletonObject = singletonFactory.getObject();
								//  记录在缓存中，二级缓存和三级缓存的对象不能同时存在
								// ====== 三级缓存返回的早期对象放到了二级缓存
								//记录在缓存中，earlySingletonObjects和singletonFactories互斥
								this.earlySingletonObjects.put(beanName, singletonObject);
								//  从三级缓存中移除
								// ====== 同时移除三级缓存
								this.singletonFactories.remove(beanName);
							}
						}
					}
				}
			}
		}
		// ====== 返回这个单例对象，如果上面if不满足，那就是个null
		return singletonObject;
	}

	/**
	 * Return the (raw) singleton object registered under the given name,
	 * creating and registering a new one if none registered yet.
	 * @param beanName the name of the bean
	 * @param singletonFactory the ObjectFactory to lazily create the singleton
	 * with, if necessary
	 * @return the registered singleton object
	 */
	//  返回以给定名称注册的(原始)单例对象，如果尚未注册，则创建并注册一个对象
	/**
	 * ======
	 * 从1级缓存里查，如果没有，参数传给我一个factory
	 * 我通过这个factory来创建你需要的bean
	 * 创建完成后，我把他放入1级，清除2、3级缓存
	 * 这个方法会确保你调用后1级缓存里的bean已经准备就绪
	 */
	public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		//  如果beanName为null，抛出异常
		Assert.notNull(beanName, "Bean name must not be null");
		//  使用单例对象的高速缓存Map作为锁，保证线程同步
		//全局变量需要同步
		synchronized (this.singletonObjects) {
			//  从单例对象的高速缓存Map中获取beanName对应的单例对象
			// ====== 单例模式！
			//首先检查对应的bean是否已经加载过，因为singleton模式其实就是复用已创建的bean，所以这一步是必须的
			Object singletonObject = this.singletonObjects.get(beanName);
			// 如果单例对象获取不到
			//如果为空才可以进行singleton的bean的初始化
			if (singletonObject == null) {
				//  如果当前在destorySingletons中
				// ====== 正在销毁的单例
				if (this.singletonsCurrentlyInDestruction) {
					throw new BeanCreationNotAllowedException(beanName,
							"Singleton bean creation not allowed while singletons of this factory are in destruction " +
							"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
				}
				//  如果当前日志级别时调试
				if (logger.isDebugEnabled()) {
					logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
				}
				//  创建单例之前的回调,默认实现将单例注册为当前正在创建中
				// ====== 扔到创建中的名单里去，这个在一开始的getSingleton里判断用
				beforeSingletonCreation(beanName);
				//  表示生成了新的单例对象的标记，默认为false，表示没有生成新的单例对象
				boolean newSingleton = false;
				//  有抑制异常记录标记,没有时为true,否则为false
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				//  如果没有抑制异常记录
				if (recordSuppressedExceptions) {
					//  对抑制的异常列表进行实例化(LinkedHashSet)
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					//  从单例工厂中获取对象
					// ====== 藏在这里！！！调用createBean方法
					// ====== 这个singletonFactory就是lambda的实现
					//初始化bean,调用传入的singletonFactory的getObject(lamda表达式)中的createBean(beanName, mbd, args)
					singletonObject = singletonFactory.getObject(); // ====> debug in
					//  生成了新的单例对象的标记为true，表示生成了新的单例对象
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
					//  同时，单例对象是否隐式出现 -> 如果是，请继续操作，因为异常表明该状态
					//  尝试从单例对象的高速缓存Map中获取beanName的单例对象
					// Has the singleton object implicitly appeared in the meantime ->
					// if yes, proceed with it since the exception indicates that state.
					singletonObject = this.singletonObjects.get(beanName);
					//  如果获取失败，抛出异常
					if (singletonObject == null) {
						throw ex;
					}
				}
				//  捕捉Bean创建异常
				catch (BeanCreationException ex) {
					//  如果没有抑制异常记录
					if (recordSuppressedExceptions) {
						//  遍历抑制的异常列表
						for (Exception suppressedException : this.suppressedExceptions) {
							//  将抑制的异常对象添加到 bean创建异常 中，这样做的，就是相当于 '因XXX异常导致了Bean创建异常‘ 的说法
							ex.addRelatedCause(suppressedException);
						}
					}
					//  抛出异常
					throw ex;
				}
				finally {
					//  如果没有抑制异常记录
					if (recordSuppressedExceptions) {
						//  将抑制的异常列表置为null，因为suppressedExceptions是对应单个bean的异常记录，置为null
						//  可防止异常信息的混乱
						this.suppressedExceptions = null;
					}
					//  创建单例后的回调,默认实现将单例标记为不在创建中
					afterSingletonCreation(beanName);
				}
				//  生成了新的单例对象
				// ###### 添加到单例池
				if (newSingleton) {
					//  将beanName和singletonObject的映射关系添加到该工厂的单例缓存中
					// ====== bean实例化完后 ，干掉三级，放到一级缓存，
					// ====== 如果没有循环依赖的话，不会经过二级，3升1
					// 加入缓存
					addSingleton(beanName, singletonObject);
				}
			}
			//  返回该单例对象
			return singletonObject;
		}
	}

	/**
	 * Register an exception that happened to get suppressed during the creation of a
	 * singleton bean instance, e.g. a temporary circular reference resolution problem.
	 * <p>The default implementation preserves any given exception in this registry's
	 * collection of suppressed exceptions, up to a limit of 100 exceptions, adding
	 * them as related causes to an eventual top-level {@link BeanCreationException}.
	 * @param ex the Exception to register
	 * @see BeanCreationException#getRelatedCauses()
	 */
	//  将要注册的异常对象添加到 抑制异常列表中，注意抑制异常列表【#suppressedExceptions】是Set集合
	protected void onSuppressedException(Exception ex) {
		//  使用singletonObject同步加锁
		synchronized (this.singletonObjects) {
			//  如果抑制异常列表不为null
			if (this.suppressedExceptions != null && this.suppressedExceptions.size() < SUPPRESSED_EXCEPTIONS_LIMIT) {
				//  将要注册的异常对象添加到抑制异常列表中，注意抑制异常列表是Set集合
				this.suppressedExceptions.add(ex);
			}
		}
	}

	/**
	 * Remove the bean with the given name from the singleton cache of this factory,
	 * to be able to clean up eager registration of a singleton if creation failed.
	 * @param beanName the name of the bean
	 * @see #getSingletonMutex()
	 */
	// 从该工厂单例缓存中删除具有给定名称的Bean。如果创建失败，则能够清理饿汉式注册的单例
	protected void removeSingleton(String beanName) {
		// 同步，使用单例对象的高速缓存:beam名称-bean实例作为锁
		synchronized (this.singletonObjects) {
			// 删除单例对象的高速缓存:beam名称-bean实例的对应数据
			this.singletonObjects.remove(beanName);
			// 删除单例工厂的缓存：bean名称-ObjectFactory的对应数据
			this.singletonFactories.remove(beanName);
			// 删除早期单例对象的高速缓存:beam名称-bean实例的对应数据
			this.earlySingletonObjects.remove(beanName);
			// 删除已注册的单例集: 按照注册顺序包含bean名 的对应数据
			this.registeredSingletons.remove(beanName);
		}
	}

	// 只是判断一下beanName是否在该BeanFactory的单例对象的高速缓存Map集合
	@Override
	public boolean containsSingleton(String beanName) {
		return this.singletonObjects.containsKey(beanName);
	}

	@Override
	public String[] getSingletonNames() {
		synchronized (this.singletonObjects) {
			return StringUtils.toStringArray(this.registeredSingletons);
		}
	}

	@Override
	public int getSingletonCount() {
		synchronized (this.singletonObjects) {
			return this.registeredSingletons.size();
		}
	}


	public void setCurrentlyInCreation(String beanName, boolean inCreation) {
		Assert.notNull(beanName, "Bean name must not be null");
		if (!inCreation) {
			this.inCreationCheckExclusions.add(beanName);
		}
		else {
			this.inCreationCheckExclusions.remove(beanName);
		}
	}

	/** 
	 *  给定的bean名是否正在创建
	 *  @param beanName
	 *  @return
	 */
	public boolean isCurrentlyInCreation(String beanName) {
		Assert.notNull(beanName, "Bean name must not be null");
		// 如果当前在创建检查中排除的bean名列表中不包含该beanName且beanName实际上正在创建就返回true.
		return (!this.inCreationCheckExclusions.contains(beanName) && isActuallyInCreation(beanName));
	}

	/** 
	 *  给定的bean名实际上是否正在创建
	 *  @param beanName
	 *  @return
	 */
	protected boolean isActuallyInCreation(String beanName) {
		return isSingletonCurrentlyInCreation(beanName);
	}

	/**
	 * Return whether the specified singleton bean is currently in creation
	 * (within the entire factory).
	 * @param beanName the name of the bean
	 */
	//  返回指定的单例bean当前是否正在创建（在整个工厂内）
	public boolean isSingletonCurrentlyInCreation(@Nullable String beanName) {
		//  从当前正在创建的bean名称set集合中判断beanName是否在集合中
		return this.singletonsCurrentlyInCreation.contains(beanName);
	}

	/**
	 * Callback before singleton creation.
	 * <p>The default implementation register the singleton as currently in creation.
	 * @param beanName the name of the singleton about to be created
	 * @see #isSingletonCurrentlyInCreation
	 */
	// 创建单例之前的回调
	protected void beforeSingletonCreation(String beanName) {
		// 如果当前在创建检查中的排除bean名列表中不包含该beanName且将beanName添加到当前正在创建的bean名称列表后，出现
		// beanName已经在当前正在创建的bean名称列表中添加过
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
			// 抛出当前正在创建的Bean异常
			throw new BeanCurrentlyInCreationException(beanName);
		}
	}

	/**
	 * Callback after singleton creation.
	 * <p>The default implementation marks the singleton as not in creation anymore.
	 * @param beanName the name of the singleton that has been created
	 * @see #isSingletonCurrentlyInCreation
	 */
	// 创建单例后的回调
	protected void afterSingletonCreation(String beanName) {
		// 如果当前在创建检查中的排除bean名列表中不包含该beanName且将beanName从当前正在创建的bean名称列表移除后，出现
		// beanName已经没在当前正在创建的bean名称列表中
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
			// 抛出非法状态异常：单例'beanName'不是当前正在创建的
			throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
		}
	}


	/**
	 * Add the given bean to the list of disposable beans in this registry.
	 * <p>Disposable beans usually correspond to registered singletons,
	 * matching the bean name but potentially being a different instance
	 * (for example, a DisposableBean adapter for a singleton that does not
	 * naturally implement Spring's DisposableBean interface).
	 * @param beanName the name of the bean
	 * @param bean the bean instance
	 */
	// 将给定Bean添加到注册中心的一次性Bean列表中
	public void registerDisposableBean(String beanName, DisposableBean bean) {
		// 使用disposableBeans加锁，保证线程安全
		synchronized (this.disposableBeans) {
			// 将beanName,bean添加到disposableBeans中
			this.disposableBeans.put(beanName, bean);
		}
	}

	/**
	 * Register a containment relationship between two beans,
	 * e.g. between an inner bean and its containing outer bean.
	 * <p>Also registers the containing bean as dependent on the contained bean
	 * in terms of destruction order.
	 * @param containedBeanName the name of the contained (inner) bean
	 * @param containingBeanName the name of the containing (outer) bean
	 * @see #registerDependentBean
	 */
	// 将containedBeanName和containingBeanName的包含关系注册到该工厂中
	public void registerContainedBean(String containedBeanName, String containingBeanName) {
		// 使用containedBeanMap作为锁，保证线程安全
		synchronized (this.containedBeanMap) {
			// 从containedBeanMap中获取containgBeanNamed的内部Bean名列表，没有时创建一个初始化长度为8的LinkedHashSet来使用
			Set<String> containedBeans =
					this.containedBeanMap.computeIfAbsent(containingBeanName, k -> new LinkedHashSet<>(8));
			// 将containedBeanName添加到containedBeans中，如果已经添加过了，就直接返回
			if (!containedBeans.add(containedBeanName)) {
				return;
			}
		}
		// 注册containedBeanName与containingBeanName的依赖关系
		registerDependentBean(containedBeanName, containingBeanName);
	}

	/**
	 * Register a dependent bean for the given bean,
	 * to be destroyed before the given bean is destroyed.
	 * @param beanName the name of the bean
	 * @param dependentBeanName the name of the dependent bean
	 */
	//  注册beanName与dependentBeanName的依赖关系
	public void registerDependentBean(String beanName, String dependentBeanName) {
		String canonicalName = canonicalName(beanName);

		synchronized (this.dependentBeanMap) {
			Set<String> dependentBeans =
					this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
			if (!dependentBeans.add(dependentBeanName)) {
				return;
			}
		}

		synchronized (this.dependenciesForBeanMap) {
			Set<String> dependenciesForBean =
					this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
			dependenciesForBean.add(canonicalName);
		}
	}

	/**
	 * Determine whether the specified dependent bean has been registered as
	 * dependent on the given bean or on any of its transitive dependencies.
	 * @param beanName the name of the bean to check
	 * @param dependentBeanName the name of the dependent bean
	 * @since 4.0
	 */
	//判断beanName是否被dependentBeanName依赖
	protected boolean isDependent(String beanName, String dependentBeanName) {
		synchronized (this.dependentBeanMap) {
			return isDependent(beanName, dependentBeanName, null);
		}
	}

	private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
		if (alreadySeen != null && alreadySeen.contains(beanName)) {
			return false;
		}
		String canonicalName = canonicalName(beanName);
		Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
		if (dependentBeans == null || dependentBeans.isEmpty()) {
			return false;
		}
		if (dependentBeans.contains(dependentBeanName)) {
			return true;
		}
		if (alreadySeen == null) {
			alreadySeen = new HashSet<>();
		}
		alreadySeen.add(beanName);
		for (String transitiveDependency : dependentBeans) {
			if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Determine whether a dependent bean has been registered for the given name.
	 * @param beanName the name of the bean to check
	 */
	//确定是否已经为给定名称注册了依赖Bean关系
	protected boolean hasDependentBean(String beanName) {
		return this.dependentBeanMap.containsKey(beanName);
	}

	/**
	 * Return the names of all beans which depend on the specified bean, if any.
	 * @param beanName the name of the bean
	 * @return the array of dependent bean names, or an empty array if none
	 */
	//返回指定的bean被哪些bean依赖了
	public String[] getDependentBeans(String beanName) {
		Set<String> dependentBeans = this.dependentBeanMap.get(beanName);
		if (dependentBeans == null) {
			return new String[0];
		}
		synchronized (this.dependentBeanMap) {
			return StringUtils.toStringArray(dependentBeans);
		}
	}

	/**
	 * Return the names of all beans that the specified bean depends on, if any.
	 * @param beanName the name of the bean
	 * @return the array of names of beans which the bean depends on,
	 * or an empty array if none
	 */
	//返回指定的bean依赖了哪些bean
	public String[] getDependenciesForBean(String beanName) {
		Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(beanName);
		if (dependenciesForBean == null) {
			return new String[0];
		}
		synchronized (this.dependenciesForBeanMap) {
			return StringUtils.toStringArray(dependenciesForBean);
		}
	}


	public void destroySingletons() {
		if (logger.isTraceEnabled()) {
			logger.trace("Destroying singletons in " + this);
		}
		//  同步，使用单例对象的高速缓存:beam名称-bean实例作为锁
		synchronized (this.singletonObjects) {
			//  将当前是否在destroySingletons中的标志设置为true，表明正在destroySingletons
			this.singletonsCurrentlyInDestruction = true;
		}

		String[] disposableBeanNames;
		//  同步,使用一次性Bean实例缓存：bean名称-DisposableBean实例作为锁
		synchronized (this.disposableBeans) {
			//  复制disposableBean的key集到一个String数组
			disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
		}
		for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
			// 销毁disposableBeanNames[i])。先销毁依赖于disposableBeanNames[i])的bean,
			// 然后再销毁bean。
			destroySingleton(disposableBeanNames[i]);
		}
		// 清空映射: bean名称 -> bean包含的Bean名称集
		this.containedBeanMap.clear();
		// 清除映射: bean名称 -> 依赖于该bean的bean名称集
		this.dependentBeanMap.clear();
		// 清除映射: bean名称 -> bean依赖项的Bean名称集
		this.dependenciesForBeanMap.clear();
		// 清除此注册表中所有缓存的单例实例
		clearSingletonCache();
	}

	/**
	 * Clear all cached singleton instances in this registry.
	 * @since 4.3.15
	 */
	// 清除此注册表中所有缓存的单例实例
	protected void clearSingletonCache() {
		synchronized (this.singletonObjects) {
			this.singletonObjects.clear();
			this.singletonFactories.clear();
			this.earlySingletonObjects.clear();
			this.registeredSingletons.clear();
			this.singletonsCurrentlyInDestruction = false;
		}
	}

	/**
	 * Destroy the given bean. Delegates to {@code destroyBean}
	 * if a corresponding disposable bean instance is found.
	 * @param beanName the name of the bean
	 * @see #destroyBean
	 */
	//  销毁给定的bean。如果找到相应的一次性Bean实例，则委托给{@code destoryBean}
	public void destroySingleton(String beanName) {
		//  删除给定名称的已注册的单例（如果有）
		// ###### 先从单例池中移除掉
		// Remove a registered singleton of the given name, if any.
		removeSingleton(beanName);

		//  销毁相应的DisposableBean实例
		// Destroy the corresponding DisposableBean instance.
		//  DisposableBean:要在销毁时释放资源的bean所实现的接口.包括已注册为一次性的内部bean。
		//  在工厂关闭时调用。
		DisposableBean disposableBean;
		synchronized (this.disposableBeans) {
			disposableBean = this.disposableBeans.remove(beanName);
		}
		//  销毁给定bean,必须先销毁依赖于给定bean的bean,然后再销毁bean
		destroyBean(beanName, disposableBean);
	}

	/**
	 * Destroy the given bean. Must destroy beans that depend on the given
	 * bean before the bean itself. Should not throw any exceptions.
	 * @param beanName the name of the bean
	 * @param bean the bean instance to destroy
	 */
	// 销毁给定bean,必须先销毁依赖于给定bean的bean,然后再销毁bean,不应抛出任何异常
	protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
		// ###### dependentBeanMap表示某bean被哪些bean依赖了
		// ###### 所以现在要销毁某个bean时，如果这个Bean还被其他Bean依赖了，那么也得销毁其他Bean
		// Trigger destruction of dependent beans first...
		Set<String> dependentBeanNames;
		synchronized (this.dependentBeanMap) {
			// Within full synchronization in order to guarantee a disconnected Set
			dependentBeanNames = this.dependentBeanMap.remove(beanName);
		}
		if (dependentBeanNames != null) {
			if (logger.isTraceEnabled()) {
				logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependentBeanNames);
			}
			for (String dependentBeanName : dependentBeanNames) {
				destroySingleton(dependentBeanName);
			}
		}

		// Actually destroy the bean now...
		if (bean != null) {
			try {
				bean.destroy();
			}
			catch (Throwable ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Destruction of bean with name '" + beanName + "' threw an exception", ex);
				}
			}
		}

		// Trigger destruction of contained beans...
		Set<String> containedBeans;
		synchronized (this.containedBeanMap) {
			// Within full synchronization in order to guarantee a disconnected Set
			containedBeans = this.containedBeanMap.remove(beanName);
		}
		if (containedBeans != null) {
			for (String containedBeanName : containedBeans) {
				destroySingleton(containedBeanName);
			}
		}

		// Remove destroyed bean from other beans' dependencies.
		synchronized (this.dependentBeanMap) {
			for (Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {
				Map.Entry<String, Set<String>> entry = it.next();
				Set<String> dependenciesToClean = entry.getValue();
				dependenciesToClean.remove(beanName);
				if (dependenciesToClean.isEmpty()) {
					it.remove();
				}
			}
		}

		// Remove destroyed bean's prepared dependency information.
		this.dependenciesForBeanMap.remove(beanName);
	}

	/**
	 * Exposes the singleton mutex to subclasses and external collaborators.
	 * <p>Subclasses should synchronize on the given Object if they perform
	 * any sort of extended singleton creation phase. In particular, subclasses
	 * should <i>not</i> have their own mutexes involved in singleton creation,
	 * to avoid the potential for deadlocks in lazy-init situations.
	 */
	// 将单例互斥暴露给子类和外部协作者
	// 如果子类执行任何扩展的单例创建阶段,则它们应在给定Object上同步.特别是,子类不应在单例创建中涉及其自己的互斥体,以避免在惰性初始化情况下出现死锁的可能性
	@Override
	public final Object getSingletonMutex() {
		return this.singletonObjects;
	}

}
